<template>
  <el-row :style="{ display: disabled ? 'none' : 'block' }">
    <div class="cm-controls">
      <li class="cm-control">
        <button type="button" title="格式化" @click="onFormat">
          <i class="cm-format" />
        </button>
      </li>
    </div>
    <codemirror v-model="value" :options="options" @input="onChange" />
  </el-row>
</template>

<script>

import { codemirror } from 'vue-codemirror'

// import base style
import 'codemirror/lib/codemirror.css'

// 引入基础样式
import 'codemirror/lib/codemirror.css'

// 引入主题样式
import 'codemirror/theme/monokai.css'
// import 'codemirror/theme/base16-dark.css'
// import 'codemirror/theme/base16-light.css'
// import 'codemirror/theme/idea.css'
// import 'codemirror/theme/eclipse.css'

// 引入语言模块
import 'codemirror/mode/sql/sql.js'
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/xml/xml.js'

// // 引入js，绑定Vim
// import 'codemirror/keymap/vim.js'
// import 'codemirror/addon/dialog/dialog.js'
// import 'codemirror/addon/search/searchcursor.js'
// // 改善vim输入命令时的样式
// import 'codemirror/addon/dialog/dialog.css'
// 支持代码折叠
import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/foldcode.js'
import 'codemirror/addon/fold/foldgutter.js'
import 'codemirror/addon/fold/brace-fold.js'
import 'codemirror/addon/fold/comment-fold.js'
// 全屏模式
import 'codemirror/addon/display/fullscreen.css'
import 'codemirror/addon/display/fullscreen.js'
// 自动刷新
import 'codemirror/addon/display/autorefresh.js'
// 括号匹配
import 'codemirror/addon/edit/matchbrackets.js'
// 自动补全
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/hint/show-hint.js'
import 'codemirror/addon/hint/anyword-hint.js'
import 'codemirror/addon/hint/sql-hint.js'
import 'codemirror/addon/hint/xml-hint.js'
import 'codemirror/addon/hint/javascript-hint.js'
// 行注释
import 'codemirror/addon/comment/comment.js'
// 代码检查错误
import 'codemirror/addon/lint/lint.css'

// sql格式化
import sqlFormatter from 'sql-formatter'
// xml格式化
import xmlFormatter from 'xml-formatter'

// 本vue组件的样式（必须放在最后）
import '@/assets/phuket/css/codeMirror.css'

export default {
  name: 'PktCodeMirror',
  components: {
    codemirror
  },
  props: {
    disabled: {
      type: Boolean,
      default: false
    },
    code: {
      type: String,
      required: false,
      default: null
    },
    mode: {
      type: String,
      required: false,
      default: 'JSON'
    },
    onChange: {
      type: Function,
      required: false,
      default: () => {}
    }
  },
  data: function() {
    return {
      value: this.code,
      options: {
        mode: this.getMode(), // 语言模式
        theme: 'monokai', // 主题
        indentUnit: 4, // 缩进单位，默认2
        smartIndent: true, // 智能缩进
        indentWithTabs: true, // 使用制表符进行智能缩进
        lineNumbers: true, // 显示行号
        // keyMap: 'vim', // 绑定Vim
        lint: true,
        lineWrapping: true, // 代码折叠
        // 在行槽中添加行号显示器、折叠器、语法检测器
        gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
        foldGutter: true, // 启用行槽中的代码折叠
        autofocus: true, // 自动聚焦
        matchBrackets: true, // 匹配结束符号，比如"]、}"
        autoCloseBrackets: true, // 自动闭合符号
        styleActiveLine: true, // 显示选中行的样式
        fullScreen: false, // 全屏模式
        autoRefresh: true,
        // 快捷键
        extraKeys: {
          'Alt-/': 'autocomplete', // 唤起智能提示
          'F11': function(cm) { // 切换全屏
            cm.setOption('fullScreen', !cm.getOption('fullScreen'))
          },
          'Esc': function(cm) { // 退出全屏
            if (cm.getOption('fullScreen')) cm.setOption('fullScreen', false)
          },
          'F6': 'toggleComment', // 切换注释
          'Ctrl-Z': function(cm) { // 撤销
            cm.undo()
          },
          'F8': function(cm) { // 恢复
            cm.redo()
          }
        }
      }
    }
  },
  watch: {
    code(newval, oldVal) {
      console.log(newval, oldVal)
      this.value = newval
    }
  },
  methods: {
    getMode() {
      if (this.mode === 'JSON') {
        return 'application/json'
      } else if (this.mode === 'SQL') {
        return 'text/x-sql'
      } else if (this.mode === 'SQL') {
        return 'application/xml'
      }
      return 'application/json'
    },
    onFormat() {
      console.log('格式化', this.mode)
      if (this.mode === 'SQL') {
        this.value = sqlFormatter.format(this.value)
      } else if (this.mode === 'XML') {
        const options = { indentation: '  ', stripComments: true, collapseContent: true, lineSeparator: '\n' }
        this.value = xmlFormatter(this.value, options)
      } else if (this.mode === 'JSON') {
        const json = JSON.parse(this.value)
        this.value = JSON.stringify(json, null, '\t')
      }
    }
  }
}
</script>
